package controllers;

import com.alibaba.fastjson.JSON;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import constants.Client;
import constants.Configurations;
import constants.api.ApiContext;
import constants.api.ApiPass;
import constants.api.ApiResultBean;
import constants.api.SessionBean;
import constants.system.MemberShip;
import controllers.BaseController;
import duppentity.*;
import duppentity.annotations.Dupp;
import play.Logger;
import play.cache.Cache;
import play.mvc.Before;
import play.mvc.Finally;
import play.mvc.Http;
import play.mvc.results.Redirect;
import play.mvc.results.RenderJson;
import play.mvc.results.RenderText;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import protocol.JsonHandler;
import protocol.JsonRequest;
import protocol.SignHandler;
import utils.JsonUtils;
import utils.RequestHelper;
import utils.Utils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author zhangzc@djcars.cn
 * @create 2016/11/25
 */
public abstract class ApiController extends BaseController {


    static UserDupp userDupp = Dupps.get(UserDupp.class);
    static SysDupp sysDupp = Dupps.get(SysDupp.class);
    static FileDupp fileDupp = Dupps.get(FileDupp.class);
    static AccountDupp accountDupp = Dupps.get(AccountDupp.class);
    static StationDupp stationDupp = Dupps.get(StationDupp.class);
    static CouponDupp couponDupp = Dupps.get(CouponDupp.class);
    static RechargeDupp rechargeDupp = Dupps.get(RechargeDupp.class);
    static MerchantDupp merchantDupp = Dupps.get(MerchantDupp.class);
    static RoleDupp roleDupp = Dupps.get(RoleDupp.class);
    static ItemDupp itemDupp = Dupps.get(ItemDupp.class);

    protected static void renderText(Object text) {
        setResponseHeader();
        throw new RenderText(text == null?"":text.toString());
    }

    protected static void renderJSON(Object o) {
        setResponseHeader();
        throw new RenderJson(o);
    }
    /**
     * 跨域设置
     */
    static void setResponseHeader(){
        response.setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "X-PINGOTHER,Content-Type,openid,os,os-sdk,sid,sign,uid,uuid,vc,vn");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        if(request.headers.containsKey("origin")) {
            String origin = request.headers.get("origin").value();
            if (StringUtils.isNotEmpty(origin)) {
                response.setHeader("Access-Control-Allow-Origin", origin);
            }
        }
    }

    @Before
    public static void onBefore() {
    }

    @Finally
    static void cleanup() {
        ApiContext.apiContext.remove();
    }

    static String getSessionId() {
        String sessionId = request.headers.get("sid").value();
        return sessionId;
    }

    static String getUUid() {
        String uuid = request.headers.get("uuid").value();
        return uuid;
    }

    static Long getUid() {
        String uid = request.headers.get("uid").value();
        return NumberUtils.createLong(uid);
    }

    static SessionBean getSession() {
        String sessionId = request.headers.get("sid").value();
        if (StringUtils.isEmpty(sessionId)) {
            Logger.error("Header没有sid");
            return null;
        }
        String sessionStr = Cache.get(sessionId, String.class);
        if (StringUtils.isEmpty(sessionStr)) {
            Logger.error("Cache里面没有Session内容");
            return null;
        }
        return JSON.parseObject(sessionStr, SessionBean.class);
    }

    static Client getClient(){
        Client client = new Client();
        ApiContext apiContext = ApiContext.apiContext.get();
        client.os = apiContext.os;
        return client;
    }

    static void apiOKData(Object obj){
        ApiResultBean bean = new ApiResultBean();
        bean.code = 0;
        bean.msg = "OK";
        bean.count=0;
        bean.data = obj;
        renderJSON(bean);
    }

    static void apiOk(Object obj) {

        if (obj instanceof JsonObject) {
            JsonObject bean = new JsonObject();
            bean.addProperty("code", 0);
            bean.addProperty("msg", "OK");
            JsonObject json =JsonUtils.parse(obj.toString());
            if(json.has("total")) {
                bean.addProperty("count", json.get("total").getAsInt());
            }else{
                bean.addProperty("count", 0);
            }
            bean.add("data", json.get("list"));
            response.setContentTypeIfNotSet("application/json; charset=UTF-8");
            renderText(bean.toString());
        } else {
            ApiResultBean bean = new ApiResultBean();
            bean.code = 0;
            bean.msg = obj.toString();
            bean.count=0;
            bean.data = obj;
            renderJSON(bean);
            //renderXJSON(bean);
        }
    }

     static void apiList(JsonObject data, Object dtos){
        JsonObject result = new JsonObject();
        result.addProperty("total",data.get("total").getAsInt());
        result.add("list", JsonUtils.toJsonTree(dtos));
        apiOk(result);
    }

    static void apiOk(Object obj,Boolean longToString) {

        if (obj instanceof JsonObject) {

            JsonObject bean = new JsonObject();
            bean.addProperty("code", 0);
            bean.addProperty("msg", "OK");
            JsonObject dataJson =JsonUtils.parse(obj.toString());
            if(dataJson.has("total")) {
                bean.addProperty("count", dataJson.get("total").getAsInt());
            }else{
                bean.addProperty("count", 0);
            }
            bean.add("data", dataJson.get("list"));
            response.setContentTypeIfNotSet("application/json; charset=UTF-8");
            renderText(bean.toString());
        } else {
            ApiResultBean bean = new ApiResultBean();
            bean.code = 0;
            bean.msg = "OK";
            bean.count = 0;
            bean.data = obj;
            if (longToString) {
                renderXJSON(bean);
            }else {
                renderJSON(bean);
            }
        }
    }

    static void apiError(String msg) {
        ApiResultBean bean = new ApiResultBean();
        bean.code = 1;
        bean.msg = msg;
        bean.data = null;
        renderJSON(bean);
    }

    static void apiError(JsonObject data) {
        String msg ="操作失败";
        if (data.has("errorMsg")){
            msg = data.get("errorMsg").getAsString();
        }
        ApiResultBean bean = new ApiResultBean();
        bean.code = 1;
        bean.msg = msg;
        bean.data = null;
        renderJSON(bean);
    }

    static void apiErrorIfNull(Object obj) {
        if (obj == null) {
            apiError("资源找不到");
        }
    }

    static void apiErrorIfNull(Object obj, String errMsg) {
        if (obj == null) {
            apiError(errMsg);
        }
    }

    static void apiErrorIfNull(Object obj,String errMsg,Object result) {
        if (obj == null) {
            ApiResultBean bean = new ApiResultBean();
            bean.code = 1;
            bean.msg = errMsg;
            bean.data = (JsonObject)result;
            renderJSON(bean);
        }
    }

    static void checkRequired(Object obj, String errMsg) {
        if (obj == null) {
            apiError(errMsg+"不能为空!");
        }
    }

    /**
     * 检查返回的值是否有错误
     * @param data
     * @return
     */
    static Boolean checkResult(JsonObject data){
        Boolean result =false;
        if (data!=null && !data.has("error")){
            result =true;
        }else{
            if (data.has("error")){
                Boolean error = data.get("error").getAsBoolean();
                if (error){
                    result = false;
                }else{
                    result = true;
                }
            }
        }
        return  result;
    }

}
